#include "ai_client.h"

int client_init()
{
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (tcp_socket == -1)
    {
        perror("tcp-socket创建失败");
        return -1;
    }
    else
        printf("tcp_socket创建成功\n");

    struct sockaddr_in deepseek_server;

    deepseek_server.sin_family = AF_INET;
    deepseek_server.sin_addr.s_addr = inet_addr(SERVER_IP);
    deepseek_server.sin_port = htons(PORT);

    int connect_fd = connect(tcp_socket, (struct sockaddr *)&deepseek_server, sizeof(deepseek_server));
    if (connect_fd == -1)
    {
        perror("连接服务器失败");
        close(tcp_socket);
        return -1;
    }
    printf("连接服务器成功\n");

    return tcp_socket;
}

int client_chat(int client_fd, char *question, void (*res_handler)(char *))
{
    // 构造请求体
    char request_body[1024] = {};

    cJSON *request = cJSON_CreateObject();
    cJSON_AddStringToObject(request, "model", MODEL);

    cJSON *message_array = cJSON_AddArrayToObject(request, "messages");

    cJSON *message_item1 = cJSON_CreateObject();
    cJSON_AddStringToObject(message_item1, "role", "user");
    cJSON_AddStringToObject(message_item1, "content", question);
    cJSON_AddItemToArray(message_array, message_item1);

    cJSON_AddTrueToObject(request, "stream");

    // printf("%s", cJSON_Print(request));
    strcpy(request_body, cJSON_PrintUnformatted(request));

    cJSON_Delete(request);

    // printf("request_body\n%s\n", request_body);
    // return 0;

    char request_head[2048] = {};
    sprintf(request_head, "POST /api/chat HTTP/1.1\r\n"
                          "Host:%s\r\n"
                          "Content-Type: application/json\r\n"
                          "Content-Length: %zu\r\n"
                          "\r\n",
            SERVER_IP,
            strlen(request_body));

    char sendbuf[1024 * 3] = {};
    char recvbuff[4096] = {};

    sprintf(sendbuf, "%s%s", request_head, request_body);

    write(client_fd, sendbuf, strlen(sendbuf));

    // 流式输出处理========================================

    // 读取响应头
    int total = 0;
    while (1)
    {
        int n = read(client_fd, recvbuff + total, 1);
        if (n <= 0)
        {
            perror("读取HTTP头部失败");
            return -1;
        }
        total += n;
        if (strstr(recvbuff, "\r\n\r\n"))
            break;
    }
    // printf("head:%s\n", recvbuff);

    int len = 0;
    while (1)
    {
        char temp_buff[1024 * 10] = {};
        len = read(client_fd, temp_buff, sizeof(temp_buff));
        // printf("%s\n", temp_buff);

        char *data = strstr(temp_buff, "\r\n");
        cJSON *json_obj = cJSON_Parse(data);

        char is_done = cJSON_IsTrue(cJSON_GetObjectItem(json_obj, "done"));

        char response[1024 * 10] = {};
        strcpy(response, cJSON_GetObjectItem(cJSON_GetObjectItem(json_obj, "message"), "content")->valuestring);

        cJSON_Delete(json_obj);

        // 判断是否结束
        if (is_done)
            break;
        else // 打印回答
        {
            // printf("%s", response);
            res_handler(response); // 回调解耦
        }
    }
    // 流式输出处理========================================
    printf("\n");
    return 0;
}

// 附带上下文的聊天
int client_chat_context(int client_fd, char (*question)[1024], int num, void (*res_handler)(char *))
{
    // 构造请求体
    char request_body[1024] = {};

    cJSON *request = cJSON_CreateObject();
    cJSON_AddStringToObject(request, "model", MODEL);

    cJSON *message_array = cJSON_AddArrayToObject(request, "messages");

    cJSON *message_item = NULL;
    for (int i = 0; i < num; i++)
    {
        message_item = cJSON_CreateObject();
        cJSON_AddStringToObject(message_item, "role", "user");
        cJSON_AddStringToObject(message_item, "content", question[i]);
        cJSON_AddItemToArray(message_array, message_item);
    }

    cJSON_AddTrueToObject(request, "stream");

    // printf("%s", cJSON_Print(request));
    strcpy(request_body, cJSON_PrintUnformatted(request));

    cJSON_Delete(request);

    // printf("request_body\n%s\n", request_body);
    // return 0;

    char request_head[2048] = {};
    sprintf(request_head, "POST /api/chat HTTP/1.1\r\n"
                          "Host:%s\r\n"
                          "Content-Type: application/json\r\n"
                          "Content-Length: %zu\r\n"
                          "\r\n",
            SERVER_IP,
            strlen(request_body));

    char sendbuf[1024 * 3] = {};
    char recvbuff[4096] = {};

    sprintf(sendbuf, "%s%s", request_head, request_body);

    write(client_fd, sendbuf, strlen(sendbuf));

    // 流式输出处理========================================

    // 读取响应头
    int total = 0;
    while (1)
    {
        int n = read(client_fd, recvbuff + total, 1);
        if (n <= 0)
        {
            perror("读取HTTP头部失败");
            return -1;
        }
        total += n;
        if (strstr(recvbuff, "\r\n\r\n"))
            break;
    }
    // printf("head:%s", recvbuff);
    // printf("=============");

    while (1)
    {
        int len = 0;
        char temp_buff[1024 * 1] = {};
        // 解决tcp粘包问题
        while (1)
        {
            // 读取本次包体大小
            int n = read(client_fd, temp_buff + len, 1);
            // printf("temp------%s\n", temp_buff);

            len += n;
            if (strstr(temp_buff, "\r\n"))
            {
                sscanf(temp_buff, "%x\r\n", &len);
                break;
            }
        }
        // printf("temp_buff-%s\n", temp_buff);
        // printf("len=%d\n", len);

        read(client_fd, temp_buff, len);
        // printf("%s", temp_buff);

        // 读取末尾的\r\n
        read(client_fd, recvbuff, 2);

        cJSON *json_obj = cJSON_Parse(temp_buff);

        int is_done = cJSON_IsTrue(cJSON_GetObjectItem(json_obj, "done"));
        // printf("temp_buff:%s", cJSON_Print(json_obj));
        // printf("is_done:%d\n", is_done);

        char response[1024 * 1] = {};
        strcpy(response, cJSON_GetObjectItem(cJSON_GetObjectItem(json_obj, "message"), "content")->valuestring);

        cJSON_Delete(json_obj);

        // 判断是否结束
        if (is_done)
            break;
        else // 打印回答
        {
            // printf("%s", response);
            res_handler(response); // 回调解耦
        }

    }
    // 读取最终空包的0\r\n\r\n
    read(client_fd, recvbuff, 5);
    // int final_len = read(client_fd, recvbuff, 5);
    // printf("final lend:%d\n",final_len);
    // printf("final recvbuff:%s",recvbuff);
    // 流式输出处理========================================
    // printf("http请求正常\n");
    return 0;
}

void client_close(int client_fd)
{
    close(client_fd);
}